package com.xlh.dokka.svc.core.client;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.xlh.dokka.svc.core.model.ContainerConfig;
import lombok.Data;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;

/**
 * @author cheer
 */
@Data
public class ContainerCreateRequest {

    /**
     * 容器VNC端口
     */
    private static final String VNC_PORT = "5901/tcp";
    /**
     * 容器ssh端口
     */
    private static final String SSH_PORT = "22/tcp";

    @SuppressWarnings("unchecked")
    public ContainerCreateRequest(ContainerConfig containerConfig) {
        this.Image = containerConfig.getImage();

        if (containerConfig.getCpu() != null) {
            this.HostConfig.CpuPeriod = 100000L;
            this.HostConfig.CpuQuota = (long) (this.HostConfig.CpuPeriod * containerConfig.getCpu());
        }
        if (containerConfig.getMemory() != null)
            this.HostConfig.Memory = containerConfig.getMemory();

        if (StringUtils.isNotBlank(containerConfig.getHostname())) {
            this.Hostname = containerConfig.getHostname();
        }

        if (StringUtils.isNotBlank(containerConfig.getMounts())) {
            this.HostConfig.Binds.add(containerConfig.getMounts() + ":/data:rw");
        }

        this.ExposedPorts.put(VNC_PORT, Maps.newHashMap());
        this.ExposedPorts.put(SSH_PORT, Maps.newHashMap());

        this.HostConfig.PortBindings.put(VNC_PORT, Lists.newArrayList(Maps.newHashMap()));
        this.HostConfig.PortBindings.put(SSH_PORT, Lists.newArrayList(Maps.newHashMap()));

        if(CollectionUtils.isNotEmpty(containerConfig.getExposedPorts())){
            for (String exposedPort : containerConfig.getExposedPorts()) {
                this.ExposedPorts.put(exposedPort, Maps.newHashMap());
                this.HostConfig.PortBindings.put(exposedPort, Lists.newArrayList(Maps.newHashMap()));
            }
        }

        Map<String, Object> ulimitsMap = Maps.newHashMap();
        ulimitsMap.put("hard", 65535);
        ulimitsMap.put("name", "nofile");
        ulimitsMap.put("soft", 65535);
        this.HostConfig.Ulimits.add(ulimitsMap);
    }

    private String Hostname;

    private List<String> Env = Lists.newArrayList("PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
            "LC_ALL=zh_CN.utf8", "TERM=xterm", "LANG=zh_CN.utf8", "HOME=/root");

    private List<String> Cmd = Lists.newArrayList("/usr/sbin/init");

    private String EntryPoint;

    private String Image;

    private String WorkingDir = "/root";

    private Map<String, Map<String, String>> ExposedPorts = Maps.newHashMap();

    private String StopSignal = "SIGKILL";

    private HostConfig HostConfig = new HostConfig();

    @Data
    public static class HostConfig {

        private List<String> Binds = Lists.newArrayList("/sys/fs/cgroup/:/sys/fs/cgroup:ro");

        private Long Memory;

        private Long MemorySwap = -1L;

        private Long CpuPeriod = 0L;

        private Long CpuQuota = 0L;

        private String NetworkMode;

        private Map<String, List<Map<String, String>>> PortBindings = Maps.newHashMap();

        private List<String> CapAdd = Lists.newArrayList("SYS_ADMIN");

        private List<String> CapDrop = Lists.newArrayList("SYS_BOOT");

        private List<Map<String, Object>> Ulimits = Lists.newArrayList();

        private Long ShmSize = (long) 1 << 30;
    }
}
